package org.agilelang.fgl.parser;

/*
 AgileLang - A fourth generation language(http://www.agilelang.org).

 Copyright (C) 2013 Roderick Cusirramos (roderick20@hotmail.com)

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
import org.agilelang.object.attributes.Event;
import org.agilelang.object.attributes.View;
import org.agilelang.object.attributes.ViewForm;
import org.agilelang.object.attributes.ViewReport;
import org.agilelang.object.Controller;
import java.util.*;

public class ControllerProcess extends Process {

    private HashMap appController;
    private Class controller_class;
    private Class view_class;
    private Class viewform_class;
    private Class viewreport_class;
    private Class function_class;
    private Class event_class;

    public ControllerProcess() {
        try {
            controller_class = Class.forName("org.agilelang.object.Controller");

            view_class = Class.forName("org.agilelang.object.attributes.View");
            viewform_class = Class.forName("org.agilelang.object.attributes.ViewForm");
            viewreport_class = Class.forName("org.agilelang.object.attributes.ViewReport");
            function_class = Class.forName("org.agilelang.object.attributes.Function");
            event_class = Class.forName("org.agilelang.object.attributes.Event");
            appController = new HashMap();
        } catch (ClassNotFoundException ex) {
            error = "Error  : " + ex.toString();
        }
    }

    public boolean process(String aLine) {

        View view = new View();
        ViewForm viewform = new ViewForm();
        ViewReport viewreport = new ViewReport();
        Event event = new Event();
        org.agilelang.object.attributes.Function function_obj = new org.agilelang.object.attributes.Function();
        Controller controller;

        String nameController = this.setPluralize(aLine);
        if (this.isReservedWord(nameController.toLowerCase())) {
            this.error = "Error nombre es palabra reservada  : " + nameController;
            return false;
        }
        if (appController.containsKey(nameController)) {
            controller = (Controller) appController.get(nameController);
        } else {
            controller = new Controller();
            controller.name = nameController;
        }

        Function function = Util.getFunction(aLine);

        if (function.name.equals("define")) {
            String[] param = Util.split(function.val, ",");
            for (int i = 0; i < param.length; i++) {
                String[] paramdel = Util.split(param[i], "=");
                String name = paramdel[0];
                String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                if (Util.setField(controller_class, name, controller, value)) {
                    appController.put(controller.name, controller);
                } else {
                    error = "Error parametro de la funcion \"define\" no existe : " + name;
                    return false;
                }
            }
        } else if (function.name.equals("addView")) {
            String[] param = Util.split(function.val, ",");
            for (int i = 0; i < param.length; i++) {
                String[] paramdel = Util.split(param[i], "=");
                String name = paramdel[0];
                String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                if (!Util.setField(view_class, name, view, value)) {
                    error = "Error parametro de la funcion \"addView\" no existe : " + name;
                    return false;
                }
            }
            Object arglist[] = new Object[1];
            arglist[0] = view;
            Util.setMethod(view, controller_class, controller, "addView");
            appController.put(controller.name, controller);
        } else if (function.name.equals("addViewForm")) {
            String[] param = Util.split_comas(function.val);
            for (int i = 0; i < param.length; i++) {
                String[] paramdel = Util.split(param[i], "=");
                String name = paramdel[0];
                String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                if (!Util.setField(viewform_class, name, viewform, value)) {
                    error = "Error parametro de la funcion \"addView\" no existe : " + name;
                    return false;
                }
            }
            Object arglist[] = new Object[1];
            arglist[0] = viewform;
            Util.setMethod(viewform, controller_class, controller, "addViewForm");
            appController.put(controller.name, controller);
        } else if (function.name.equals("addViewReport")) {
            String[] param = Util.split_comas(function.val);
            for (int i = 0; i < param.length; i++) {
                String[] paramdel = Util.split(param[i], "=");
                String name = paramdel[0];
                String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                if (!Util.setField(viewreport_class, name, viewreport, value)) {
                    error = "Error parametro de la funcion \"addView\" no existe : " + name;
                    return false;
                }
            }
            Object arglist[] = new Object[1];
            arglist[0] = viewreport;
            Util.setMethod(viewreport, controller_class, controller, "addViewReport");
            appController.put(controller.name, controller);
        } else if (function.name.equals("addHeader")) {
            if (function.val.length() > 0) {
                String[] param = Util.split(function.val, ",");
                for (int i = 0; i < param.length; i++) {
                    String[] paramdel = Util.split(param[i], "=");
                    String param_name = paramdel[0];
                    switch (param_name) {
                        case "model":
                            {
                                String name = "model_header";
                                String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                                if (Util.setField(controller_class, name, controller, value)) {
                                    appController.put(controller.name, controller);
                                } else {
                                    error = "Error parametro de la funcion \"addHeader\" no existe : " + name;
                                    return false;
                                }
                                break;
                            }
                        case "description":
                            {
                                String name = "model_header_description";
                                String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                                if (Util.setField(controller_class, name, controller, value)) {
                                    appController.put(controller.name, controller);
                                } else {
                                    error = "Error parametro de la funcion \"addHeader\" no existe : " + name;
                                    return false;
                                }
                                break;
                            }
                    }

                }
            }

        } else if (function.name.equals("attributes")) {
            if (function.val.length() > 0) {
                String[] param = Util.split_comas(function.val);
                for (int i = 0; i < param.length; i++) {
                    String[] paramdel = Util.split(param[i], "=");
                    String param_name = paramdel[0];
                    if (param_name.equals("attributes")) {
                        String name = "attributesView";
                        String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                        if (Util.setField(controller_class, name, controller, value)) {
                            appController.put(controller.name, controller);
                        } else {
                            error = "Error parametro de la funcion \"addHeader\" no existe : " + name;
                            return false;
                        }
                    }
                }
            }
        } else if (function.name.equals("attributesIndex")) {
            if (function.val.length() > 0) {
                String[] param = Util.split_comas(function.val);
                for (int i = 0; i < param.length; i++) {
                    String[] paramdel = Util.split(param[i], "=");
                    String param_name = paramdel[0];
                    if (param_name.equals("attributes")) {
                        String name = "attributesIndex";
                        String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                        if (Util.setField(controller_class, name, controller, value)) {
                            appController.put(controller.name, controller);
                        } else {
                            error = "Error parametro de la funcion \"attributesIndex\" no existe : " + name;
                            return false;
                        }
                    }
                }
            }
        } else if (function.name.equals("customIndex")) {
            if (function.val.length() > 0) {
                String[] param = Util.split_comas(function.val);
                for (int i = 0; i < param.length; i++) {
                    String[] paramdel = Util.split(param[i], "=");
                    String param_name = paramdel[0];
                    switch (param_name) {
                        case "attributes": {
                            String name = "attributesIndex";
                            String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                            if (Util.setField(controller_class, name, controller, value)) {
                                appController.put(controller.name, controller);
                            } else {
                                error = "Error parametro de la funcion \"attributesIndex\" no existe : " + name;
                                return false;
                            }
                            break;
                        }
                        case "order": {
                            String name = "orderIndex";
                            String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                            if (Util.setField(controller_class, name, controller, value)) {
                                appController.put(controller.name, controller);
                            } else {
                                error = "Error parametro de la funcion \"attributesIndex\" no existe : " + name;
                                return false;
                            }
                            break;
                        }
                        case "conditions": {
                            String name = "conditionsIndex";
                            String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                            if (Util.setField(controller_class, name, controller, value)) {
                                appController.put(controller.name, controller);
                            } else {
                                error = "Error parametro de la funcion \"attributesIndex\" no existe : " + name;
                                return false;
                            }
                            break;
                        }
                    }
                }
            }
        } else if (function.name.equals("customView")) {
            if (function.val.length() > 0) {
                String[] param = Util.split_comas(function.val);
                for (int i = 0; i < param.length; i++) {
                    String[] paramdel = Util.split(param[i], "=");
                    String param_name = paramdel[0];
                    switch (param_name) {
                        case "attributes": {
                            String name = "attributesView";
                            String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                            if (Util.setField(controller_class, name, controller, value)) {
                                appController.put(controller.name, controller);
                            } else {
                                error = "Error parametro de la funcion \"attributesIndex\" no existe : " + name;
                                return false;
                            }
                            break;
                        }
                    }
                }
            }
        } 
        else if (function.name.equals("customUpdate")) {
            if (function.val.length() > 0) {
                String[] param = Util.split_comas(function.val);
                for (int i = 0; i < param.length; i++) {
                    String[] paramdel = Util.split(param[i], "=");
                    String param_name = paramdel[0];
                    switch (param_name) {
                        case "attributes": {
                            String name = "attributesUpdate";
                            String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                            if (Util.setField(controller_class, name, controller, value)) {
                                appController.put(controller.name, controller);
                            } else {
                                error = "Error parametro de la funcion \"attributesIndex\" no existe : " + name;
                                return false;
                            }
                            break;
                        }
                        case "defaults": {
                            String name = "defaultsUpdate";
                            String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                            if (Util.setField(controller_class, name, controller, value)) {
                                appController.put(controller.name, controller);
                            } else {
                                error = "Error parametro de la funcion \"attributesIndex\" no existe : " + name;
                                return false;
                            }
                            break;
                        }                        
                    }
                }
            }
        }
        
        else if (function.name.equals("customAdd")) {
            if (function.val.length() > 0) {
                String[] param = Util.split_comas(function.val);
                for (int i = 0; i < param.length; i++) {
                    String[] paramdel = Util.split(param[i], "=");
                    String param_name = paramdel[0];
                    switch (param_name) {
                        case "attributes": {
                            String name = "attributesAdd";
                            String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                            if (Util.setField(controller_class, name, controller, value)) {
                                appController.put(controller.name, controller);
                            } else {
                                error = "Error parametro de la funcion \"attributesIndex\" no existe : " + name;
                                return false;
                            }
                            break;
                        }
                        case "defaults": {
                            String name = "defaultsAdd";
                            String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                            if (Util.setField(controller_class, name, controller, value)) {
                                appController.put(controller.name, controller);
                            } else {
                                error = "Error parametro de la funcion \"attributesIndex\" no existe : " + name;
                                return false;
                            }
                            break;
                        }                        
                    }
                }
            }
        }
        else if (function.name.equals("attributesUpdate")) {
            if (function.val.length() > 0) {
                String[] param = Util.split_comas(function.val);
                for (int i = 0; i < param.length; i++) {
                    String[] paramdel = Util.split(param[i], "=");
                    String param_name = paramdel[0];
                    if (param_name.equals("attributes")) {
                        String name = "attributesUpdate";
                        String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                        if (Util.setField(controller_class, name, controller, value)) {
                            appController.put(controller.name, controller);
                        } else {
                            error = "Error parametro de la funcion \"addHeader\" no existe : " + name;
                            return false;
                        }
                    }
                }
            }
        } else if (function.name.equals("addCondition")) {
            if (function.val.length() > 0) {
                String[] param = Util.split_comas(function.val);
                for (int i = 0; i < param.length; i++) {
                    String[] paramdel = Util.split(param[i], "=");
                    String param_name = paramdel[0];
                    if (param_name.equals("condition")) {
                        String name = "addCondition";
                        String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                        if (Util.setField(controller_class, name, controller, value)) {
                            appController.put(controller.name, controller);
                        } else {
                            error = "Error parametro de la funcion \"addCondition\" no existe : " + name;
                            return false;
                        }
                    }
                }
            }
        } else if (function.name.equals("addDetail")) {
            if (function.val.length() > 0) {
                String[] param = Util.split(function.val, ",");
                for (int i = 0; i < param.length; i++) {
                    String[] paramdel = Util.split(param[i], "=");
                    String param_name = paramdel[0];
                    if (param_name.equals("model")) {
                        String name = "model_detail";
                        String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                        if (Util.setField(controller_class, name, controller, value)) {
                            appController.put(controller.name, controller);
                        } else {
                            error = "Error parametro de la funcion \"addDetail\" no existe : " + name;
                            return false;
                        }
                    } else if (param_name.equals("description")) {
                        String name = "model_detail_description";
                        String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                        if (Util.setField(controller_class, name, controller, value)) {
                            appController.put(controller.name, controller);
                        } else {
                            error = "Error parametro de la funcion \"addDetail\" no existe : " + name;
                            return false;
                        }
                    }

                }
            }
        } else if (function.name.equals("addRelation")) {
            String[] param = Util.split(function.val, ",");
            for (int i = 0; i < param.length; i++) {
                String[] paramdel = Util.split(param[i], "=");
                String name = paramdel[0];
                if (name.equals("header")) {
                    String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                    if (Util.setField(controller_class, "relation_header", controller, value)) {
                        appController.put(controller.name, controller);
                    } else {
                        error = "Error parametro de la funcion \"define\" no existe : " + name;
                        return false;
                    }
                } else if (name.equals("detail")) {
                    String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                    if (Util.setField(controller_class, "relation_detail", controller, value)) {
                        appController.put(controller.name, controller);
                    } else {
                        error = "Error parametro de la funcion \"define\" no existe : " + name;
                        return false;
                    }
                } else if (name.equals("description")) {
                    String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                    if (Util.setField(controller_class, "relation_description", controller, value)) {
                        appController.put(controller.name, controller);
                    } else {
                        error = "Error parametro de la funcion \"define\" no existe : " + name;
                        return false;
                    }
                } else if (name.equals("header_field")) {
                    String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                    if (Util.setField(controller_class, "relation_field", controller, value)) {
                        appController.put(controller.name, controller);
                    } else {
                        error = "Error parametro de la funcion \"define\" no existe : " + name;
                        return false;
                    }
                }

            }
        } else if (function.name.equals("addEvent")) {
            String[] param = Util.split(function.val, ",");
            for (int i = 0; i < param.length; i++) {
                String[] paramdel = Util.split(param[i], "=");
                String name = paramdel[0];
                String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                if (!Util.setField(event_class, name, event, value)) {
                    error = "Error parametro de la funcion \"addEvent\" no existe : " + name;
                    return false;
                }
            }
            Object arglist[] = new Object[1];
            arglist[0] = event;
            Util.setMethod(event, controller_class, controller, "addEvent");
            appController.put(controller.name, controller);
        } else if (function.name.equals("addFunction")) {
            String[] param = Util.split(function.val, ",");
            for (int i = 0; i < param.length; i++) {
                String[] paramdel = Util.split(param[i], "=");
                String name = paramdel[0];
                String value = paramdel[1].substring(1, paramdel[1].length() - 1);
                if (!Util.setField(function_class, name, function_obj, value)) {
                    error = "Error parametro de la funcion \"addFunction\" no existe : " + name;
                    return false;
                }
            }
            Object arglist[] = new Object[1];
            arglist[0] = function_obj;
            Util.setMethod(function_obj, controller_class, controller, "addFunction");
            appController.put(controller.name, controller);

        } else {
            error = "Error Funcion no existe : " + function.name;
            return false;
        }
        return true;
    }

    public List<Controller> getListController() {
        List<Controller> list = new ArrayList<Controller>();
        SortedSet<String> sortedset = new TreeSet<String>(appController.keySet());
        Iterator<String> it = sortedset.iterator();
        while (it.hasNext()) {
            Controller controller = (Controller) appController.get(it.next());
            list.add(controller);
        }
        return list;
    }
}
